#include <asm/asm.h>
#include <pmap.h>
#include <env.h>
#include <printf.h>
#include <kclock.h>
#include <trap.h>
#include <types.h>
#include <mmu.h>

extern char aoutcode[];
extern char boutcode[];
extern unsigned char _binary_envtest1_elf_start[];
extern unsigned char _binary_envtest1_elf_end[];
extern unsigned char _binary_envtest2_elf_start[];
extern unsigned char _binary_envtest2_elf_end[];
extern unsigned char _binary_idle_elf_start[];
extern unsigned char _binary_idle_elf_end[];
extern unsigned char _binary_fktest_elf_start[];
extern unsigned char _binary_fktest_elf_end[];
extern unsigned char _binary_pingpong_elf_start[];
extern unsigned char _binary_pingpong_elf_end[];
void riscv_init()
{
	printf("init.c:\tmips_init() is called\n");
	u_int64_t a,b,c;
	riscv_detect_memory();
	printf("mem dect success!\n");
	riscv_vm_init();
	page_init();

//	physical_memory_manage_check();
//	page_check();
	
	env_init();
	printf("env inited\n");

        //env_create_priority(_binary_envtest2_elf_start, _binary_envtest2_elf_end - _binary_envtest2_elf_start, 2);
	//printf("env2 created\n");

	//env_create_priority(_binary_envtest1_elf_start, _binary_envtest1_elf_end - _binary_envtest1_elf_start, 1);
	//printf("env1 created\n");

	//env_create_priority(_binary_idle_elf_start, _binary_idle_elf_end - _binary_idle_elf_start, 1);

	env_create_priority(_binary_fktest_elf_start, _binary_fktest_elf_end - _binary_fktest_elf_start, 1);

	//env_create_priority(_binary_pingpong_elf_start, _binary_pingpong_elf_end - _binary_pingpong_elf_start, 1);

	kclock_init();
	printf("kclock_init succ\n");
	panic("init.c:\tend of mips_init() reached!");
}

void bcopy(const void *src, void *dst, size_t len)
{
	void *max;
//printf("bcopy from %lx to %lx, len %lx\n", src, dst, len);
	max = dst + len;
	// copy machine words while possible
	while (dst + 7 < max)
	{
		*(u_int64_t *)dst = *(u_int64_t *)src;
		dst+=8;
		src+=8;
	}
	// copy machine words while possible
	while (dst + 3 < max)
	{
		*(int *)dst = *(int *)src;
		dst+=4;
		src+=4;
	}
	// finish remaining 0-3 bytes
	while (dst < max)
	{
		*(char *)dst = *(char *)src;
		dst+=1;
		src+=1;
	}
}

void bzero(void *b, size_t len)
{
	void *max;

	max = b + len;

	// printf("init.c:\tzero from %lx to %lx\n",b,max);
	
	// zero machine words while possible
	while ((u_int64_t)(b + 7) < (u_int64_t)max)
	{
		*(u_int64_t *)b = 0;
		b+=8;
	}

	while ((u_int64_t)(b + 3) < (u_int64_t)max)
	{
		*(int *)b = 0;
		b+=4;
	}
	
	// finish remaining 0-3 bytes
	while ((u_int64_t)b < (u_int64_t)max)
	{
		*(char *)b++ = 0;
	}		
	// printf("bzero succ!\n");
}
